<template>
  <div>
    <a-collapse :default-active-key="[1, 2, 3, 4]" :bordered="false">
      <a-collapse-item header="热区设置" :key="2">
        <div class="chooseBox">
          <p class="titles">热区图片</p>
          <a-upload
            action="/app/file/upload"
            :show-file-list="false"
            @success="onSuccessBgImage3($event)"
            @error="errorBgImage3($event)"
            :image-preview="true"
          >
            <template #upload-button>
              <div
                class="arco-upload-list-picture custom-upload-avatar"
                v-if="currentTemp.mainImage"
              >
                <img
                  style="display: block; width: 80px; height: 80px"
                  :src="currentTemp.mainImage"
                />
                <div class="arco-upload-list-picture-mask">
                  <IconEdit />
                </div>
              </div>
              <div class="arco-upload-picture-card" v-else>
                <div class="arco-upload-picture-card-text">
                  <IconPlus />
                </div>
              </div>
              <!-- </div> -->
            </template>
          </a-upload>
        </div>
        <div class="addImageBox" @click="setRequ"> 编辑热区 </div>
      </a-collapse-item>
      <a-collapse-item header="间距(px)" :key="2">
        <div class="sliderBox">
          <p>上边距</p>
          <a-slider
            v-model="currentTemp.paddingTop"
            show-input
            style="width: 100%"
            :min="0"
            :max="100"
          />
        </div>
        <div class="sliderBox">
          <p>下边距</p>
          <a-slider
            v-model="currentTemp.paddingBottom"
            show-input
            style="width: 100%"
            :min="0"
            :max="100"
          />
        </div>
        <div class="sliderBox">
          <p>左右边距</p>
          <a-slider
            v-model="currentTemp.paddingTwice"
            show-input
            style="width: 100%"
            :min="0"
            :max="100"
          />
        </div>
      </a-collapse-item>
      <a-collapse-item header="圆角设置(px)" :key="3">
        <div class="sliderBox">
          <p>上圆角</p>
          <a-slider
            v-model="currentTemp.radiusNumTop"
            show-input
            style="width: 100%"
            :min="0"
            :max="100"
          />
        </div>
        <div class="sliderBox">
          <p>下圆角</p>
          <a-slider
            v-model="currentTemp.radiusNumBottom"
            show-input
            style="width: 100%"
            :min="0"
            :max="100"
          />
        </div>
      </a-collapse-item>
      <a-collapse-item header="背景设置" :key="4">
        <div class="chooseBox">
          <p class="title">展示类型</p>
          <div class="radioBox">
            <a-radio-group v-model="currentTemp.showType">
              <a-radio :value="1">
                <template #radio="{ checked }">
                  <div style="display: flex" :class="{ 'custom-radio-card-checked': checked }">
                    <div className="custom-radio-card-mask">
                      <div className="custom-radio-card-mask-dot"></div>
                    </div>
                    <div className="custom-radio-card-title">颜色</div>
                  </div>
                </template>
              </a-radio>
              <a-radio :value="2">
                <template #radio="{ checked }">
                  <div style="display: flex" :class="{ 'custom-radio-card-checked': checked }">
                    <div className="custom-radio-card-mask">
                      <div className="custom-radio-card-mask-dot"></div>
                    </div>
                    <div className="custom-radio-card-title">图片</div>
                  </div>
                </template>
              </a-radio>
            </a-radio-group>
          </div>
        </div>
        <div class="uploadBox" style="margin-bottom: 10px" v-if="currentTemp.showType == 2">
          <a-upload
            action="/app/file/upload"
            :show-file-list="false"
            @success="onSuccessBgImage($event)"
            @error="errorBgImage($event)"
            :image-preview="true"
          >
            <template #upload-button>
              <div class="arco-upload-list-picture custom-upload-avatar" v-if="currentTemp.bgImage">
                <img style="display: block; width: 80px; height: 80px" :src="currentTemp.bgImage" />
                <div class="arco-upload-list-picture-mask">
                  <IconEdit />
                </div>
              </div>
              <div class="arco-upload-picture-card" v-else>
                <div class="arco-upload-picture-card-text">
                  <IconPlus />
                </div>
              </div>
              <!-- </div> -->
            </template>
          </a-upload>
        </div>

        <div class="sliderBox_color2" v-if="currentTemp.showType == 1">
          <p style="width: 100%; margin-bottom: 5px">填充颜色</p>
          <div
            style="
              width: 40px;
              height: 40px;
              cursor: pointer;
              border: 6px solid #f5f5f5;
              border-radius: 4px;
            "
            :style="{ backgroundColor: currentTemp.boxBg }"
            @click="changSketch3"
          ></div>

          <Sketch
            class="setColor"
            v-model="currentTemp.boxBg"
            :show="colorForm.showSketchBg"
            @changButton="changSketchBg"
          />

          <a-button type="text" style="margin-left: 12px" @click="currentTemp.boxBg = '#ffffff'"
            >重置</a-button
          >
        </div>
      </a-collapse-item>
    </a-collapse>

    <a-modal v-model:visible="requData.showModal" @cancel="handleCancel" fullscreen>
      <template #title>编辑热区 </template>
      <div class="requBox">
        <div class="hotspot-editor">
          <!-- 图片容器 -->
          <div
            class="image-container"
            ref="containerRef"
            @mousedown="startAction"
            @mousemove="handleMove"
            @mouseup="endAction"
            @mouseleave="cancelAction"
            @touchstart.passive="startAction"
            @touchmove.passive="handleMove"
            @touchend.passive="endAction"
          >
            <img
              :src="currentTemp.mainImage"
              class="target-image"
              draggable="false"
              mode="widthFix"
            />

            <!-- 热区显示 -->
            <div
              v-for="(hotspot, index) in hotspots"
              :key="index"
              class="hotspot"
              :style="getHotspotStyle(hotspot)"
              @mousedown="startDrag(index, $event)"
              @touchstart="startDrag(index, $event)"
              @dblclick="showSetLink(index, hotspot)"
            >
              <div class="closeBtn" @click="delItem(index, $event)">
                <icon-close style="font-size: 20px; color: #fff" />
              </div>
              <div class="textsLine">
                <span class="names">热区{{ index + 1 }}</span>
                <span class="weishe" v-if="hotspot.link == ''">(未设置)</span>
                <span class="yishe" v-else>(已设置)</span>
              </div>
              <!-- 调整手柄 -->
              <div class="resize-handle" @mousedown.stop="startResize(index, $event)"></div>
            </div>

            <!-- 选择框 -->
            <div v-if="isSelecting" class="selection-box" :style="selectionStyle"></div>
          </div>
        </div>
        <div class="rightBox">
          <p class="titles"> 图片热区 </p>
          <a-alert>框选热区范围，双击设置热区信息</a-alert>
          <div class="inputList">
            <div class="itemIpt" v-for="(item, index) in hotspots" :key="index">
              <p class="names"> 热区{{ index + 1 }} </p>
              <a-input
                :style="{ width: '320px' }"
                v-model="item.link"
                placeholder="请输入跳转链接"
                allow-clear
              >
                <template #suffix> <icon-link /> </template>
              </a-input>
              <icon-delete @click="delItem(index)" style="font-size: 20px; margin-left: 10px" />
            </div>
          </div>
        </div>
      </div>
      <template #footer>
        <a-space>
          <a-button @click="handleCancel">取消</a-button>
          <a-button type="primary" @click="handleOk">确定</a-button>
        </a-space>
      </template>
    </a-modal>
    <a-modal
      v-model:visible="tagvisible"
      @cancel="handleCancelTag"
      title="设置链接"
      width="600px"
      :mask-closable="false"
      title-align="start"
    >
      <a-form ref="userFormTag" :auto-label-width="true" :model="subForm">
        <a-form-item
          v-if="subForm.type == 1"
          label="跳转链接"
          field="links"
          :rules="[
            { required: true, message: '跳转链接不能为空' },
            { minLength: 1, maxLength: 100, message: '跳转链接必须小于100个字符' },
          ]"
          :validate-trigger="['change', 'input']"
        >
          <a-input v-model.trim="subForm.links" placeholder="请输入跳转链接" allow-clear />
        </a-form-item>
      </a-form>
      <template #footer>
        <a-space>
          <a-button @click="handleCancelTag">取消</a-button>
          <a-button type="primary" @click="handleBeforeOkLink">确定</a-button>
        </a-space>
      </template>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
  import { Sketch } from '@ans1998/vue3-color'
  import { Message } from '@arco-design/web-vue'
  import { computed, watch, ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
  const tagvisible = ref(false)
  const emit = defineEmits(['change'])
  const props = defineProps({
    // 选中的当前组件参数
    config: {
      type: Object,
      default: () => {
        return {}
      },
    },
    menus: {
      type: Array,
      required: true,
    },
  })
  const requData = reactive({ showModal: false, requlinks: [] })
  const colorForm = ref({ showSketchBg: false, showSketchFont: false })
  const typeLists = ref([
    { id: 1, name: '自定义' },
    { id: 2, name: '系统功能' },
  ])
  const setRequ = () => {
    requData.showModal = true
    hotspots.value = currentTemp.value.links
  }
  // 响应式数据
  const hotspots = ref([])
  const containerRef = ref(null)

  // 交互状态
  const actionType = ref(null) // 'select' | 'drag' | 'resize'
  const startPos = ref({ x: 0, y: 0 })
  const currentPos = ref({ x: 0, y: 0 })
  const activeIndex = ref(-1)
  const isSelecting = ref(false)

  // 坐标转换
  const getRelativePosition = (clientX, clientY) => {
    const rect = containerRef.value.getBoundingClientRect()
    let a = {
      x: (clientX - rect.left) / rect.width,
      y: (clientY - rect.top) / rect.height,
    }
    // console.log(clientX, clientY, rect, a)
    return {
      x: (clientX - rect.left) / rect.width,
      y: (clientY - rect.top) / rect.height,
    }
  }
  // 事件处理
  const startAction = (e) => {
    const { clientX, clientY } = e.touches?.[0] || e
    const pos = getRelativePosition(clientX, clientY)
    startPos.value = pos
    currentPos.value = pos
    isSelecting.value = true
    actionType.value = 'select'
  }
  const handleMove = (e) => {
    const { clientX, clientY } = e.touches?.[0] || e
    currentPos.value = getRelativePosition(clientX, clientY)

    // 更新热区位置/尺寸
    if (actionType.value === 'drag') {
      updateHotspotPosition()
    } else if (actionType.value === 'resize') {
      updateHotspotSize()
    } else {
    }
  }

  const endAction = () => {
    if (actionType.value === 'select') {
      createHotspot()
    }
    resetState()
  }
  const cancelAction = () => {
    resetState()
  }
  // 热区操作
  const startDrag = (index, e) => {
    e.stopPropagation()
    actionType.value = 'drag'
    activeIndex.value = index
    startPos.value = getRelativePosition(e.clientX, e.clientY)
  }
  const delItem = (index, e) => {
    hotspots.value.splice(index, 1)
  }
  const startResize = (index, e) => {
    e.stopPropagation()
    actionType.value = 'resize'
    activeIndex.value = index
    startPos.value = getRelativePosition(e.clientX, e.clientY)
  }

  const updateHotspotPosition = () => {
    const deltaX = currentPos.value.x - startPos.value.x
    const deltaY = currentPos.value.y - startPos.value.y
    const hotspot = hotspots.value[activeIndex.value]
    const newX = Math.max(0, Math.min(hotspot.x + deltaX, 1 - hotspot.width))
    const newY = Math.max(0, Math.min(hotspot.y + deltaY, 1 - hotspot.height))
    nextTick(() => {
      hotspots.value[activeIndex.value] = {
        ...hotspot,
        x: newX,
        y: newY,
      }
      startPos.value = currentPos.value
    })
  }

  const updateHotspotSize = () => {
    const deltaX = currentPos.value.x - startPos.value.x
    const deltaY = currentPos.value.y - startPos.value.y
    const hotspot = hotspots.value[activeIndex.value]

    const newWidth = Math.max(0.05, Math.min(hotspot.width + deltaX, 1 - hotspot.x))
    const newHeight = Math.max(0.05, Math.min(hotspot.height + deltaY, 1 - hotspot.y))

    hotspots.value[activeIndex.value] = {
      ...hotspot,
      width: newWidth,
      height: newHeight,
    }

    startPos.value = currentPos.value
  }

  const createHotspot = () => {
    const minX = Math.min(startPos.value.x, currentPos.value.x)
    const minY = Math.min(startPos.value.y, currentPos.value.y)
    const width = Math.abs(currentPos.value.x - startPos.value.x)
    const height = Math.abs(currentPos.value.y - startPos.value.y)

    if (width > 0.02 && height > 0.02) {
      hotspots.value.push({
        link: '',
        x: minX,
        y: minY,
        width,
        height,
      })
    }
  }

  const resetState = () => {
    isSelecting.value = false
    actionType.value = null
    activeIndex.value = -1
  }

  // 样式计算
  const selectionStyle = computed(() => ({
    left: `${Math.min(startPos.value.x, currentPos.value.x) * 100}%`,
    top: `${Math.min(startPos.value.y, currentPos.value.y) * 100}%`,
    width: `${Math.abs(currentPos.value.x - startPos.value.x) * 100}%`,
    height: `${Math.abs(currentPos.value.y - startPos.value.y) * 100}%`,
  }))

  const getHotspotStyle = (hotspot) => ({
    left: `${hotspot.x * 100}%`,
    top: `${hotspot.y * 100}%`,
    width: `${hotspot.width * 100}%`,
    height: `${hotspot.height * 100}%`,
  })

  // 持久化
  const saveHotspots = () => {
    const data = hotspots.value.map((h) => ({
      ...h,
      x: Number(h.x.toFixed(4)),
      y: Number(h.y.toFixed(4)),
      width: Number(h.width.toFixed(4)),
      height: Number(h.height.toFixed(4)),
    }))
    console.log('热区数据:', JSON.stringify(data, null, 2))
    // 实际使用时替换为API调用
  }
  const handleOk = () => {
    // 使用every方法检查每个对象的link属性是否都不为空
    const allLinksValid = hotspots.value.every((item) => item.link !== '')

    if (!allLinksValid) {
      // 可以选择在这里抛出错误或者进行其他错误处理
      Message.error('请设置热区链接！')
      return false
    } else {
      requData.showModal = false
      currentTemp.value.links = hotspots.value
    }
  }
  const handleCancel = () => {
    requData.showModal = false
  }
  const changSketchBg = (item: any) => {
    colorForm.value.showSketchBg = false
    console.log(item)
    if (item.isOk) {
      currentTemp.value.boxBg = item.activeColor
    } else {
      console.log('取消')
    }
  }
  const changSketch3 = () => {
    colorForm.value.showSketchBg = true
  }
  //背景图上传
  const onSuccessBgImage = (e: any) => {
    currentTemp.value.bgImage = e.response.data.path
    console.log(e)
  }
  const errorBgImage = (e: any) => {
    console.log(e)
    currentTemp.value.bgImage = e.response.data.path
  }
  //背景图上传
  const onSuccessBgImage3 = (e: any) => {
    currentTemp.value.mainImage = e.response.data.path
    console.log(e)
  }
  const errorBgImage3 = (e: any) => {
    console.log(e)
    currentTemp.value.mainImage = e.response.data.path
  }
  const linkLists: any = computed(() => props.menus)
  const subForm = ref({
    type: 1,
    links: '',
    idx: 0,
  })
  const currentTemp = computed(() => props.config)
  console.log(currentTemp.value)
  watch(
    () => currentTemp,
    (newVal, oldVal) => {
      emit('change', newVal.value)
    },
    { immediate: true, deep: true }
  )
  //背景图上传
  const onSuccessBcg = (fileItem: any) => {
    currentTemp.value.icon1 = fileItem.response.data.path
  }
  const onSuccessBcg2 = (fileItem: any) => {
    currentTemp.value.icon2 = fileItem.response.data.path
  }
  const showSetLink = (index, val) => {
    subForm.value.index = index
    subForm.value.links = val.link
    tagvisible.value = true
  }
  const handleCancelTag = () => {
    subForm.value = { type: 1, links: '', idx: 0, index: '' }
    tagvisible.value = false
  }
  const chooseLink = (val: any) => {
    subForm.value.idx = val
    tagvisible.value = true
  }
  const userFormTag = ref()
  const handleBeforeOkLink = () => {
    userFormTag.value?.validate().then((error: any) => {
      if (!error) {
        hotspots.value[subForm.value.index].link = subForm.value.links
        tagvisible.value = false
      }
    })
  }
</script>

<style scoped lang="less">
  :deep(.arco-alert-info) {
    background-color: rgb(var(--arcoblue-2)) !important;
    color: #fff !important;
  }
  .requBox {
    width: 100%;
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    padding: 0px calc((100% - 1200px) / 2);
    box-sizing: border-box;
    .rightBox {
      flex: 1;
      .titles {
        font-size: 24px;
        font-weight: bold;
        margin-bottom: 20px;
      }
      .inputList {
        width: 100%;
        .names {
          width: 60px;
          margin-right: 12px;
        }
        .itemIpt {
          display: flex;
          align-items: center;
          margin-top: 10px;
        }
      }
    }
  }
  .hotspot-editor {
    position: relative;
    width: 750px;
    margin-right: 20px;
  }

  .image-container {
    width: 100%;
    position: relative;
    display: inline-block;
    user-select: none;
    touch-action: none;
  }

  .target-image {
    display: block;
    width: 100%;
    height: auto;
  }

  .selection-box {
    position: absolute;
    background: rgba(66, 153, 242, 0.2);
    border: 2px solid #4299f2;
    pointer-events: none;
  }

  .hotspot {
    position: absolute;
    background: rgba(24, 144, 255, 0.5);
    border: 1px dashed #1890ff;
    cursor: move;
    transition: all 0.2s;
    display: flex;
    justify-content: center;
    align-items: center;
  }
  .closeBtn {
    cursor: pointer;
    width: 20px;
    height: 20px;
    background-color: #1890ff;
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    right: 0px;
    top: 0px;
  }
  .textsLine {
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    .names {
      font-size: 12px;
      color: #fff;
    }
    .weishe {
      font-size: 12px;
      color: rgb(255, 0, 0);
    }
    .yishe {
      font-size: 12px;
      color: #1890ff;
    }
  }
  .resize-handle {
    position: absolute;
    right: -4px;
    bottom: -4px;
    width: 8px;
    height: 8px;
    background: #fff;
    border: 1px solid #1890ff;
    border-radius: 50%;
    cursor: nwse-resize;
  }

  .debug-info {
    margin-top: 1rem;
    padding: 1rem;
    background: #f5f5f5;
    pre {
      white-space: pre-wrap;
    }
  }
  :deep(.arco-upload-picture-card) {
    background: var(--color-bg-1);
  }
  :deep(.arco-collapse-item-content) {
    padding: 4px 0px;
    background: #fff;
    border: none;
    overflow: visible;
  }
  :deep(.arco-collapse-item-content-box) {
    padding: 0px 10px;
  }
  :deep(.arco-collapse-item-header) {
    border: none;
  }
  :deep(.arco-collapse-item) {
    border: none;
  }
  :deep(.arco-slider-track::before) {
    height: 4px;
  }
  :deep(.arco-slider-bar) {
    height: 4px;
  }
  :deep(.arco-collapse-item .arco-collapse-item-icon-hover) {
    position: absolute;
    top: 50%;
    left: 4px;
  }
  :deep(.arco-collapse-item-header-left) {
    padding-left: 24px;
  }
  .sliderBox_color2 {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    margin-bottom: 10px;
    position: relative;
    z-index: 10;
    overflow: visible;
    p {
      min-width: 50px;
      display: inline-block;
      margin-right: 12px;
    }
    .setColor {
      position: absolute;
      left: 120px;
      bottom: 30px;
      z-index: 1000000;
    }
  }
  .addImageBox {
    width: 100%;
    height: 35px;
    text-align: center;
    line-height: 35px;
    background: #f5f5f5;
    color: #333;
    font-size: 14px;
    cursor: pointer;
  }
  .chooseBox {
    width: 100%;
    margin: 0px 0px 10px;
    display: flex;
    flex-wrap: wrap;
    .titles {
      width: 100%;
      display: block;
      margin-bottom: 5px;
    }
    .beizhu {
      font-size: 11px;
      color: #86909c;
      margin-top: 5px;
    }
    .radioBox {
      width: 100%;
      background-color: #f5f5f5;
      border-radius: 4px;
      height: 35px;
      display: flex;
      align-items: center;
      padding: 0px 10px;
      box-sizing: border-box;
    }
  }
  .imageBox {
    .imageBox_item:first-child {
      margin-bottom: 10px;
    }
    .imageBox_item {
      width: 100%;
      height: 110px;
      display: flex;
      background-color: #f5f5f5;
      padding: 15px 20px;
      box-sizing: border-box;
      display: flex;
      align-items: center;
      .rightBox {
        height: 100%;
        padding: 4px 0px 4px 10px;
        box-sizing: border-box;
        flex-grow: 1;
        display: flex;
        flex-wrap: wrap;
        align-content: space-between;
        .chooseBtn {
          padding: 0px 10px !important;
          display: flex !important;
          justify-content: flex-start !important;
          background-color: #fff !important;
          border: none !important;
          color: #86909c !important;
          .chooseText {
            margin-left: 6px;
          }
        }
        .texts {
          font-size: 12px;
          color: #1d1929;
        }
      }
    }
  }
  .sliderBox {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 10px;
    p {
      width: 50px;
      display: inline-block;
      margin-right: 12px;
    }
  }
  .sliderBox_color {
    display: flex;
    align-items: center;
    margin-bottom: 10px;
    position: relative;
    z-index: 10;
    overflow: visible;
    p {
      min-width: 50px;
      display: inline-block;
      margin-right: 12px;
    }
    .setColor {
      position: absolute;
      left: 120px;
      bottom: 30px;
      z-index: 1000000;
    }
  }
  .sliderBox:last-child {
    margin-bottom: 0px;
  }
</style>
